package cn.cdm.rabbitmq;


import cn.cdm.domain.MiaoshaOrder;
import cn.cdm.domain.MiaoshaUser;
import cn.cdm.domain.OrderInfo;
import cn.cdm.redis.GoodsKey;
import cn.cdm.redis.RedisService;
import cn.cdm.service.GoodsService;
import cn.cdm.service.MiaoshaService;
import cn.cdm.service.OrderService;
import cn.cdm.vo.GoodsVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MQReceiver {
    private static final Logger log = LoggerFactory.getLogger(MQReceiver.class);

    @Autowired
    MiaoshaService miaoshaService;

    @Autowired
    RedisService redisService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private GoodsService goodsService;

    /**
     * 请求出队，生成订单，减库存
     * 将秒杀和下订单这两个流程解耦，当用户秒杀成功后，将用户和商品id存入MQ队列；
     * 消费者去该队列去数据，然后减数据库中的库存、下订单。
     *
     * todo 若用户秒杀成功了，下单之后，在15分钟之内还未完成支付的话，该订单会被自动取消，需要回退库存。
     *                             若用户在15分钟之内支付成功，则将order_info表的该商品的订单状态修改为已支付。
     * 使用RabbitMQ的死信队列
     * @param message
     */
//    @RabbitListener(queues = {MQConfig.MIAOSHA_QUEUE})
    @RabbitListener(queues = MQConfig.MIAOSHA_QUEUE)
    public void receiveMiaosha(String message){
        log.info("miaosha.queue队列，监听消息：{}" + message);
        MiaoshaMessage miaoshaMessage = RedisService.stringToBean(message, MiaoshaMessage.class);

        MiaoshaUser miaoshaUser = miaoshaMessage.getUser();
        long goodsId = miaoshaMessage.getGoodsId();
        // 根据商品id，查询秒杀商品表中的商品对象
        GoodsVo goodsVo = goodsService.getGoodsVoByGoodsId(goodsId);

        // 查询数据库中该秒杀商品的库存数量
        int stock = goodsVo.getStockCount();
        if (stock <= 0) {
            return;
        }

        // 判断是否已经秒杀到了，防止某个用户重复成功秒杀
        MiaoshaOrder miaoshaOrder = orderService.getMiaoshaOrderByUserIdGoodsId(
                miaoshaUser.getId(), goodsId);
        if (miaoshaOrder != null) {
            log.error("用户重复秒杀，用户id：{}；秒杀商品id：{}", miaoshaUser.getId(), goodsId);
            return;
        }
        // 减库存、下订单，写入秒杀订单
        miaoshaService.miaosha(miaoshaUser, goodsVo);
        log.info("秒杀成功，用户id：{}；秒杀商品id：{}", miaoshaUser.getId(), goodsId);
        // todo 如何告诉前端，提示该用户秒杀成功了呢？具体如下：
        // 后端提供一个秒杀结果查询的接口，如“/miaosha/result”，前端每隔1秒钟，来轮询该接口，判断用户是否秒杀成功！
        // 若该接口返回 -1，表示秒杀失败；0排列中；其他，则返回秒杀的订单号。

    }

    @RabbitListener(queues = "queue")
    public void receive(String message){
        log.info("mq receive : " + message);
    }

    @RabbitListener(queues = "topic.queue1")
    public void receiveTopicQueue1(String message){
        log.info("mq topic.key1 receive : " + message);
    }
    @RabbitListener(queues = "topic.queue2")
    public void receiveTopicQueue2(String message){
        log.info("mq topic.# : " + message);
    }
}
